/** @file    CoderXML_Automations.cpp
 *  @author  Alessandro Polo
 *  @version $Id: CoderXML_Automations.cpp 2061 2010-03-09 00:14:12Z alex $
 *  @brief
 * File containing methods for Serialization.
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

 #include <framework/database/CoderXML_Automations.h>
 #include <framework/database/CoderXML_Core.h>
 #include <framework/database/EncoderXML.h>


using namespace std;
using namespace wosh::automations;
namespace wosh {
 namespace database {

void EncoderXML_register_Automations()
 {
	EncoderXML::registerDataType( "wosh::automations::AutomationMessage",	new EncoderXML_template__AutomationMessage() );
	EncoderXML::registerDataType( "wosh::automations::AutomationDeviceLink",new EncoderXML_template__AutomationDeviceLink() );
	
	EncoderXML::registerDataType( "wosh::automations::CronJob",				new EncoderXML_template__CronJob() );
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Automation::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::automations::Automation* object = dynamic_cast<const wosh::automations::Automation*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	if ( compact ) {
		ret += EncoderXML_template__Object().serializeTo( object, doc, contNode, true );

	 }
	else {
		QDomElement objectNode = doc.createElement("object");
		contNode.appendChild(objectNode);
		ret += EncoderXML_template__Object().serializeTo( object, doc, objectNode, false );

	 }

	if ( object->isEnabled() )
		contNode.setAttribute("enabled", "true" );
	else
		contNode.setAttribute("enabled", "false" );

	QDomElement node_properties= doc.createElement("properties");
	ret += EncoderXML_template__PropertiesProvider().serializeTo( &object->getProperties(), doc, node_properties, compact );
	contNode.appendChild(node_properties);

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__Automation::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::automations::Automation* object = dynamic_cast<wosh::automations::Automation*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	QDomElement objectNode = contNode.namedItem("object").toElement();
	if ( !objectNode.isNull() )
		ret += EncoderXML_template__Object().deserializeFrom( object, objectNode );
	else
		ret += EncoderXML_template__Object().deserializeFrom( object, contNode );

	if ( contNode.attribute("enabled").toUpper() == "FALSE" )
		object->setEnabled(false);

	QDomElement propsNode = contNode.namedItem("properties").toElement();
	if ( !propsNode.isNull() ) {
		ret += EncoderXML_template__PropertiesProvider().deserializeFrom( &object->getProperties(), propsNode );
	 }

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__AutomationMessage::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::automations::AutomationMessage* object = dynamic_cast<const wosh::automations::AutomationMessage*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__Automation().serializeTo( object_s, doc, contNode, compact );
	(void)object;

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__AutomationMessage::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::automations::AutomationMessage* object = dynamic_cast<wosh::automations::AutomationMessage*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__Automation().deserializeFrom( object_s, contNode );

	EncoderXML_template__MessageFilter msgFilterEncoder;
	QDomElement triggers = contNode.namedItem("triggers").toElement();
	if ( !triggers.isNull() ) {
		QDomNodeList nodesList = triggers.childNodes();
		for( unsigned int j=0; j<nodesList.length(); ++j ) {
			QDomElement childNode = nodesList.item(j).toElement();
			MessageFilter * message = new MessageFilter();
			msgFilterEncoder.deserializeFrom( message , childNode );
			object->addTigger(message );
		 }
	 }

	EncoderXML_template__Message msgEncoder;
	QDomElement effects = contNode.namedItem("effects").toElement();
	if ( !effects.isNull() ) {
		QDomNodeList nodesList = effects.childNodes();
		for( unsigned int j=0; j<nodesList.length(); ++j ) {
			QDomElement childNode = nodesList.item(j).toElement();
			Message* message = new Message();
			msgEncoder.deserializeFrom( message , childNode );
			object->addEffect(message );
		 }
	 }

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__AutomationDeviceLink::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::automations::AutomationDeviceLink* object = dynamic_cast<const wosh::automations::AutomationDeviceLink*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__Automation().serializeTo( object_s, doc, contNode, compact );
	(void)object;

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__AutomationDeviceLink::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::automations::AutomationDeviceLink* object = dynamic_cast<wosh::automations::AutomationDeviceLink*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__Automation().deserializeFrom( object_s, contNode );

	EncoderXML_template__MessageFilter msgFilterEncoder;
	QDomElement mappings_node = contNode.namedItem("mappings").toElement();
	if ( !mappings_node.isNull() ) {
		QDomNodeList nodesList = mappings_node.childNodes();
		for( unsigned int j=0; j<nodesList.length(); ++j ) {
			QDomElement childNode = nodesList.item(j).toElement();
			DeviceTrigger* trigger = NULL;
			DeviceEffect* effect = NULL;

			QDomElement event_node = childNode.namedItem("event").toElement();
			if ( !event_node.isNull() ) {
				trigger = new DeviceTrigger();
				trigger->source = string( childNode.namedItem("source").toElement().text().toLatin1().data());
				trigger->event_name = string( event_node.attribute("name").toLatin1().data());
				trigger->event_data.fromString( string( event_node.attribute("data").toLatin1().data()));
			 }
			else
				continue;

			QDomElement method_node = childNode.namedItem("method").toElement();
			if ( !method_node.isNull() ) {
				effect = new DeviceEffect();
				effect->target = string( childNode.namedItem("target").toElement().text().toLatin1().data());
				effect->method_name = string( method_node.attribute("name").toLatin1().data());
				effect->method_arg.fromString( string( method_node.attribute("arg").toLatin1().data()) );
			 }
			else
				continue;

				object->addMapping(trigger, effect);
		 }
	 }

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__CronJob::serializeTo( const ISerializable* object_s, QDomDocument& doc, QDomElement& contNode, bool compact )
 {
	if ( object_s == NULL ) return WRET_ERR_PARAM;
	const wosh::automations::CronJob* object = dynamic_cast<const wosh::automations::CronJob*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__AutomationMessage().serializeTo( object_s, doc, contNode, compact );
	(void)object;

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

WRESULT EncoderXML_template__CronJob::deserializeFrom( ISerializable* object_s, const QDomElement& contNode )
 {
 	if ( object_s == NULL ) return WRET_ERR_PARAM;
	wosh::automations::CronJob* object = dynamic_cast<wosh::automations::CronJob*>(object_s);
	if ( object == NULL ) return WRET_ERR_PARAM;
	WRESULT ret = WRET_OK;

	ret = EncoderXML_template__Automation().deserializeFrom( object_s, contNode );

	QDomElement scheduleNode = contNode.namedItem("schedule").toElement();
	if ( !scheduleNode.isNull() ) {
		QDomElement node_year = scheduleNode.namedItem("year").toElement();
		if ( node_year.isNull() )
			object->setYear( scheduleNode.attribute("year").toInt() );
		else
			object->setYear( node_year.text().toInt() );

		QDomElement node_month = scheduleNode.namedItem("month").toElement();
		if ( node_month.isNull() )
			object->setMonth( scheduleNode.attribute("month").toInt() );
		else
			object->setMonth( node_month.text().toInt() );

		QDomElement node_day = scheduleNode.namedItem("day").toElement();
		if ( node_day.isNull() )
			object->setDay( scheduleNode.attribute("day").toInt() );
		else
			object->setDay( node_day.text().toInt() );

		QDomElement node_hour = scheduleNode.namedItem("hour").toElement();
		if ( node_hour.isNull() )
			object->setHour( scheduleNode.attribute("hour").toInt() );
		else
			object->setHour( node_hour.text().toInt() );

		QDomElement node_min = scheduleNode.namedItem("min").toElement();
		if ( node_min.isNull() )
			object->setMin( scheduleNode.attribute("min").toInt() );
		else
			object->setMin( node_min.text().toInt() );

		QDomElement node_sec = scheduleNode.namedItem("sec").toElement();
		if ( node_sec.isNull() )
			object->setSec( scheduleNode.attribute("sec").toInt() );
		else
			object->setSec( node_sec.text().toInt() );

	 }

	EncoderXML_template__Message msgEncoder;
	QDomElement effects = contNode.namedItem("effects").toElement();
	if ( !effects.isNull() ) {
		QDomNodeList nodesList = effects.childNodes();
		for( unsigned int j=0; j<nodesList.length(); ++j ) {
			QDomElement childNode = nodesList.item(j).toElement();
			Message* message = new Message();
			msgEncoder.deserializeFrom( message , childNode );
			object->addEffect(message );
		 }
	 }

	return ret;
 }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

 }; // namespace database
}; // namespace wosh
